/**
 @file drv_ftm.h

 @date 2011-11-16

 @version v2.0

 alloc memory and offset
*/

#ifndef _SYS_GOLDENGATE_FTM_H
#define _SYS_GOLDENGATE_FTM_H
#ifdef __cplusplus
extern "C" {
#endif
#include "drv_api.h"

#define DRV_FTM_MEM_MAX (64)

#define DRV_FTM_INIT_LPM_SIZE(lchip,max_mem_id,tcam_key)  \
    (0xFFFF==(max_mem_id) || !TCAM_END_INDEX(lchip, tcam_key, max_mem_id) ? 0 : TCAM_END_INDEX(lchip, tcam_key, max_mem_id)+1)

#define DRV_FTM_INIT_CHECK(lchip) \
    do { \
        if (NULL == g_usw_ftm_master[lchip]){ \
            return DRV_E_NOT_INIT; } \
    } while (0)

#define DRV_FTM_DBG_OUT(fmt, args...)       sal_printf(fmt, ##args)
#define DRV_FTM_DBG_DUMP(fmt, args...)

enum drv_ftm_cam_type_e
{
    DRV_FTM_CAM_TYPE_INVALID        = 0,
    DRV_FTM_CAM_TYPE_FIB_HOST0,
    DRV_FTM_CAM_TYPE_FIB_HOST1,
    DRV_FTM_CAM_TYPE_FIB_MAC,
    DRV_FTM_CAM_TYPE_IGR_SCL0,
    DRV_FTM_CAM_TYPE_IGR_SCL1,
    DRV_FTM_CAM_TYPE_XC,
    DRV_FTM_CAM_TYPE_RMEP,
    DRV_FTM_CAM_TYPE_FLOW,
    DRV_FTM_CAM_TYPE_MPLS_HASH,
    DRV_FTM_CAM_TYPE_GEM_PORT,
    DRV_FTM_CAM_TYPE_EGR_SCL,
    DRV_FTM_CAM_TYPE_EGR_SCL1,
    DRV_FTM_CAM_TYPE_QUEUE,
    DRV_FTM_CAM_TYPE_XSEC_RX,
    DRV_FTM_CAM_TYPE_XSEC_TX,
    DRV_FTM_CAM_TYPE_MAX
};
typedef enum drv_ftm_cam_type_e drv_ftm_cam_type_t;

#define DRV_FTM_TCAM_SIZE_80  0
#define DRV_FTM_TCAM_SIZE_160 1
#define DRV_FTM_TCAM_SIZE_320 2
#define DRV_FTM_TCAM_SIZE_640 3

struct drv_ftm_tbl_info_s
{
    uint32  tbl_id;                             /**ctc_ftm_tbl_type_t*/
    uint32 mem_bitmap[2];                       /**Table allocation in which SRAM*/
    uint32 mem_start_offset[DRV_FTM_MEM_MAX];   /**Start Offset of SRAM*/
    uint32 mem_entry_num[DRV_FTM_MEM_MAX];      /**Entry number in SRAM*/
};
typedef struct drv_ftm_tbl_info_s drv_ftm_tbl_info_t;

/**
 @brief Profile key information
*/
struct drv_ftm_key_info_s
{
    uint8  key_size;
    uint32 max_key_index;
    uint8  key_media;
    uint8  key_id;

    uint32 tcam_bitmap[DRV_FTM_MEM_MAX/32+1];
    uint32 tcam_start_offset[DRV_FTM_MEM_MAX];
    uint32 tcam_entry_num[DRV_FTM_MEM_MAX];
};
typedef struct drv_ftm_key_info_s drv_ftm_key_info_t;

struct drv_ftm_cam_s
{
    uint8 conflict_cam_num[DRV_FTM_CAM_TYPE_MAX];
};
typedef struct drv_ftm_cam_s drv_ftm_cam_t;

struct drv_ftm_profile_info_s
{
    drv_ftm_key_info_t* key_info;   /**< [HB.GB]Profile key information*/
    uint16 key_info_size;           /**< [HB.GB]Size of key_info, multiple of sizeof(ctc_ftm_key_info_t) */
    uint8 profile_type;             /**< [GB]Profile type, refer to ctc_ftm_profile_type_t*/
    uint8 lpm_mode;

    uint32 couple_mode:1;
    uint32 napt_enable:1;
    uint32 mpls_mode:2;             /* 0,disable; 1:not couple; 2,couple mode*/
    uint32 scl_mode:1;
    uint32 mpls_en:1;
    uint32 nsh_num:8;                  /**< [AT] nsh edit num(unit/k), support 0,1,2,3,4 and 8 */
    uint32 rsv:18;
    drv_ftm_tbl_info_t* tbl_info;               /**< [GB]table information  */
    uint16 tbl_info_size;                       /**< [GB]Size of tbl_info, multiple of sizeof(ctc_ftm_tbl_info_t) */

    drv_ftm_cam_t cam_info;
};
typedef struct drv_ftm_profile_info_s drv_ftm_profile_info_t;

enum drv_ftm_lpm_model_type_e
{
    LPM_MODEL_PUBLIC_IPDA,                              /* only public Ipda */
    LPM_MODEL_PRIVATE_IPDA,                             /* only private ipda */
    LPM_MODEL_PUBLIC_IPDA_IPSA_HALF,            /* public ipda+ipsa, half size, performance */
    LPM_MODEL_PUBLIC_IPDA_IPSA_FULL,             /* public ipda+ipsa, full size, no performance */
    LPM_MODEL_PUBLIC_IPDA_PRIVATE_IPDA_HALF, /* public and private ipda, half size, performance */
    LPM_MODEL_PRIVATE_IPDA_IPSA_HALF,           /* private ipda+ipsa, half size, performance */
    LPM_MODEL_PRIVATE_IPDA_IPSA_FULL,           /* private ipda+ipsa, full size, no performance, default Mode */
    LPM_MODEL_PUBLIC_IPDA_IPSA_PRIVATE_IPDA_IPSA_HALF /* public ipda+ipsa, private ipda+ipsa, half size, no performance */
};
typedef enum drv_ftm_lpm_model_type_e drv_ftm_lpm_model_type_t;


enum drv_ftm_tbl_detail_type_e
{
    DRV_FTM_TBL_TYPE,
};
typedef enum drv_ftm_tbl_detail_type_e drv_ftm_tbl_detail_type_t;

enum drv_ftm_table_type_e
{
    DRV_FTM_TABLE_STATIC,
    DRV_FTM_TABLE_DYNAMIC,
    DRV_FTM_TABLE_TCAM_KEY,
};
typedef enum drv_ftm_table_type_e drv_ftm_table_type_t;

struct drv_ftm_tbl_detail_s
{
    uint8 type;                /*< [GG]drv_ftm_tbl_detail_type_t */
    uint32 tbl_id;

    uint8 tbl_type;
};
typedef struct drv_ftm_tbl_detail_s drv_ftm_tbl_detail_t;

enum drv_ftm_mem_type_e
{
    DRV_FTM_MEM_DYNAMIC,
    DRV_FTM_MEM_TCAM,

    DRV_FTM_MEM_DYNAMIC_KEY,
    DRV_FTM_MEM_DYNAMIC_AD,
    DRV_FTM_MEM_DYNAMIC_EDIT,

    DRV_FTM_MEM_TCAM_FLOW_KEY,
    DRV_FTM_MEM_TCAM_I_SCL0_KEY,
    DRV_FTM_MEM_TCAM_I_SCL1_KEY,
    DRV_FTM_MEM_TCAM_I_ACL_KEY,
    DRV_FTM_MEM_TCAM_E_ACL_KEY,
    DRV_FTM_MEM_TCAM_E_SCL_KEY,
    DRV_FTM_MEM_TCAM_LPM_KEY,
    DRV_FTM_MEM_TCAM_CID_KEY,
    DRV_FTM_MEM_TCAM_QUEUE_KEY,
    DRV_FTM_MEM_LTID,
    DRV_FTM_MEM_UDF,
    DRV_FTM_MEM_RT_MAC,

    DRV_FTM_MEM_TCAM_FLOW_AD,
    DRV_FTM_MEM_TCAM_LPM_AD,
    DRV_FTM_MEM_MIXED_KEY,
    DRV_FTM_MEM_MIXED_AD,
    DRV_FTM_MEM_MIXED_CAM,

    DRV_FTM_MEM_TCAM_SEL_KEY,
    DRV_FTM_MEM_TCAM_RMAC,

    DRV_FTM_MEM_DYNAMIC_OAM,
    DRV_FTM_MEM_DYNAMIC_IPFIX,
    DRV_FTM_MEM_LTID1,
    DRV_FTM_MEM_DYNAMIC_QUEUE,
    DRV_FTM_MEM_DYNAMIC_XSEC_RX,
    DRV_FTM_MEM_DYNAMIC_XSEC_TX,

    DRV_FTM_MEM_SHARE_MEM,
};
typedef enum drv_ftm_mem_type_e drv_ftm_mem_type_t;

#define DRV_USW_FTM_EXTERN_MEM_ID_BASE  8

#define DRV_ENTRY_SIZE_ALINE(entry_size, entry_offset) \
    if ((entry_size) <= 4) {\
        (entry_offset) = 4;\
    } else if ((entry_size) <= 8) {\
        (entry_offset) = 8;\
    } else if ((entry_size) <= 16) {\
        (entry_offset) = 16;\
    } else if ((entry_size) <= 32) {\
        (entry_offset) = 32;\
    } else if ((entry_size) <= 64) {\
        (entry_offset) = 64;\
    } else {\
        (entry_offset) = 128;\
    }

extern  int32
drv_ftm_get_tbl_detail(uint8 lchip, drv_ftm_tbl_detail_t* p_tbl_info);

extern int32
drv_usw_ftm_ram_with_chip_op(uint8 lchip, uint8 ram_id);


extern  int32
drv_ftm_get_tbl_detail(uint8 lchip, drv_ftm_tbl_detail_t* p_tbl_info);

extern int32
drv_usw_ftm_table_id_2_mem_id(uint8 lchip, uint32 tbl_id, uint32 tbl_idx, uint32* p_mem_id, uint32* p_offset);

extern int32
drv_usw_get_memory_size(uint8 lchip, uint32 mem_id, uint32*p_mem_size);

extern int32
drv_usw_ftm_get_cam_by_tbl_id(uint8 lchip, uint32 tbl_id, uint8* cam_type, uint8* cam_num);

extern int32
drv_usw_ftm_set_misc_config(uint8 lchip);

extern int32
drv_usw_ftm_adjust_flow_tcam(uint8 lchip, uint8 expand_key, uint8 compress_key);

extern int32
drv_usw_ftm_adjust_mac_table(uint8 lchip, drv_ftm_profile_info_t* p_profile);

extern int32
drv_usw_ftm_reset_tcam_table(uint8 lchip);
extern int32 drv_usw_ftm_adjust_flow_tcam(uint8 lchip, uint8 expand_key, uint8 compress_key);
extern int32 drv_usw_ftm_adjust_mac_table(uint8 lchip, drv_ftm_profile_info_t* p_profile);
extern int32 drv_usw_ftm_reset_tcam_table(uint8 lchip);
extern uint8
drv_usw_ftm_sram_use_sdb(uint8 lchip, uint8 ram_id);

extern int32
drv_usw_ftm_reset_dynamic_table(uint8 lchip);
extern int32
drv_usw_ftm_alloc_tcam(uint8 lchip, uint8 start_key_type, uint8 end_key_type, uint8 force_realloc);
extern int32
drv_usw_ftm_get_lpm_tcam_init_size(uint8 lchip, uint8 lpm_model, uint32 (*lpm_tcam_init_bmp)[3], drv_ftm_info_detail_t* p_ftm_info);
extern uint32
drv_usw_ftm_memid_2_table(uint8 lchip, uint32 mem_id);
#ifdef __cplusplus
}
#endif

#endif

